package cn.remex.core.quartz;

import cn.remex.RemexConstants;
import cn.remex.core.exception.ServiceCode;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;

import java.util.Collection;
import java.util.Date;

import static cn.remex.core.quartz.Task.TriggerType.once;


/**
 * @author liuhengyang 
 * date 2014-10-14 上午11:58:38
 * @version 版本号码
 */

public class Scheduler {
	private org.quartz.Scheduler scheduler;
	private String schedulerName;

	Scheduler(String schedulerName, org.quartz.Scheduler scheduler) {
		this.scheduler = scheduler;
		this.schedulerName = schedulerName;
	}

	/* 新增一个任务，并按预定时间启动。 */
	public void addTask(Task task) {
		try {
			JobDetail jobDetail = task.obtainJobDetail();
			Trigger trigger = task.obtainTrigger();

			if(!scheduler.checkExists(trigger.getKey())
					|| !scheduler.checkExists(trigger.getKey())){

				scheduler.scheduleJob(jobDetail, trigger);
			}else if(!task.isIgnoreWhenExsite()){
				throw new QuartzException(ServiceCode.QUARTZ_ERROR, "任务重复异常,scheduler="+schedulerName+",triggerKey="+trigger.getKey()+",jobKey="+jobDetail.getKey());
			}else {
				RemexConstants.logger.warn("忽略已存任务,triggerKey={},jobKey={},scheduler={}", trigger.getKey(), jobDetail.getKey(), schedulerName);
			}
			RemexConstants.logger.info("添加新增任务,triggerKey={},jobKey={},scheduler={}", trigger.getKey(), jobDetail.getKey(), schedulerName);

		} catch (SchedulerException e) {
			RemexConstants.logger.info("添加新增任务异常,triggerKey={},jobKey={},scheduler={}", task.getTriggerName(), task.getJobName(), scheduler, e);
			throw new QuartzException(ServiceCode.QUARTZ_ERROR, "任务安排失败！", e);
		}
	}

	public boolean checkExists(Task task) {
		try {
			return scheduler.checkExists(task.obtainTrigger().getKey())
					|| scheduler.checkExists(task.obtainJobDetail().getKey());
		} catch (SchedulerException e) {
			throw new QuartzException(ServiceCode.QUARTZ_ERROR, "检查任务是否存在失败", e);
		}
	}


	/*从当前计划中按指定要求停止并删除一个任务 */
	public boolean deleteTask(Task task) {
		boolean b = false;
		TriggerKey triggerKey = TriggerKey.triggerKey(task.getTriggerName(), task.getGroup());
		JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getGroup());
		try {
			scheduler.pauseTrigger(triggerKey);
			scheduler.unscheduleJob(triggerKey);
			b = scheduler.deleteJob(jobKey);
		} catch (SchedulerException e) {
			RemexConstants.logger.error("移除任务异常,scheduler={},triggerKey={},jobKey={}", schedulerName, triggerKey, jobKey);
			return b;
		}
		RemexConstants.logger.info("移除任务,scheduler={},triggerKey={},jobKey={}", schedulerName, triggerKey, jobKey);
		return b;
	}
	public void deleteTask(String triggerKeyStr) {
		TriggerKey triggerKey = TriggerKey.triggerKey(triggerKeyStr);
		try {
			scheduler.pauseTrigger(triggerKey);
			scheduler.unscheduleJob(triggerKey);
		} catch (SchedulerException e) {
			RemexConstants.logger.error("移除任务异常,scheduler={},triggerKey={},jobKey=", schedulerName, triggerKey);
		}
		RemexConstants.logger.info("移除任务,scheduler={},triggerKey={},jobKey=", schedulerName, triggerKey);
	}

	/* 启动按预定时间启动一次该任务	 */
	public void onceTask(Class<? extends Job> jobClass, Date date, Object... jobParams) {
		Task task = new Task(jobClass).triggerType(once).startAt(date);
		if (null != jobParams && 0 < jobParams.length && jobParams.length % 2 == 0)
			for (int i = 0, s = jobParams.length; i < s; i = i + 2) {
				task.putJobParams(jobParams[i].toString(), jobParams[i + 1]);
			}
		addTask(task);
	}

	public void restart() {
		RemexConstants.logger.info("重启任务调度日程,scheduler={}", schedulerName);
		shutdown();
		againStart();
	}

	/*  重新启动当前日程 */
	public void againStart() {
		try {
			scheduler.start();
		} catch (SchedulerException e) {
			throw new QuartzException(ServiceCode.QUARTZ_ERROR, "重新启动日程失败！", e);
		}
	}

	/*  启动当前日程 */
	public void start() {
		try {
			scheduler.start();
		} catch (SchedulerException e) {
			throw new QuartzException(ServiceCode.QUARTZ_ERROR, "启动日程失败！", e);
		}
	}

	public void start(Collection<Task> tasks) {
		if (tasks != null) {
			for (Task temp : tasks) {
				addTask(temp);
			}
		}
		start();
	}

	/* 停止当前任务 */
	public void shutdown() {
		if (scheduler != null) {
			try {
				scheduler.shutdown(true);
			} catch (SchedulerException e) {
				throw new QuartzException(ServiceCode.QUARTZ_ERROR, "停止日程失败！", e);
			} finally {
				scheduler = null;
			}
		}
	}

	public org.quartz.Scheduler getScheduler() {
		return scheduler;
	}
}


